// Copyright (c) 2005  INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of cgal-python; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; version 2.1 of the License.
// See the file LICENSE.LGPL distributed with cgal-python.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $Id: Py_Min_ellipse_2.cpp 167 2007-11-02 15:36:54Z spion $
// $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal-python/trunk/cgal-python/bindings/Geometric_Optimisation/Py_Min_ellipse_2.cpp $
//
// Author(s)     : Naceur Meskini
//=========================================================================

// include ====================================================================
#include <CGAL/basic.h>
#include <include/Kernels.h>
#include <include/iterator.h>

#include <CGAL/Min_ellipse_2.h>
#include <CGAL/Min_ellipse_2_traits_2.h>

#include <boost/python.hpp>
#include <boost/cstdint.hpp>
#include <list>
#include "Py_Min_ellipse_2_doc.h"


// Using =======================================================================
using namespace boost::python;

// Declarations ================================================================
namespace
{

BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(is_valid_overloads_0_2, is_valid, 0, 2)

}// namespace 

template<class Point_iterator,class Min_ellipse_2>
simple_python_iterator<Point_iterator> points(const Min_ellipse_2& me)
{
	std::pair< Point_iterator , Point_iterator > p( me.points_begin(), me.points_end() );
	return simple_python_iterator<Point_iterator>(p);
}

template<class Support_point_iterator,class Min_ellipse_2>
simple_python_iterator<Support_point_iterator> support_points(const Min_ellipse_2& me)
{
	std::pair< Support_point_iterator , Support_point_iterator > p( me.support_points_begin(), me.support_points_end() );
	return simple_python_iterator<Support_point_iterator>(p);
}

template<class Min_ellipse_2>
void insert_list(Min_ellipse_2& me,const boost::python::list& pts)
{
	typedef typename Min_ellipse_2::Point Point;
	int N = boost::python::extract<int>(pts.attr("__len__")());
	for(int i = 0 ; i < N ; i++)
	{
		Point P = boost::python::extract<Point>(pts[i]); 
		me.insert(P);
	}
}


template<class kernel>
void Py_Min_ellipse_2()
{
	typedef typename kernel::Point_2 Point_2;
	typedef CGAL::Min_ellipse_2_traits_2<kernel > ellipse_2_trait;
	typedef CGAL::Min_ellipse_2<ellipse_2_trait> Min_ellipse_2;
	typedef typename Min_ellipse_2::Point_iterator 			Point_iterator;
	typedef typename Min_ellipse_2::Support_point_iterator 	Support_point_iterator;

     class_< Min_ellipse_2, boost::noncopyable >("Min_ellipse_2", Min_ellipse_2_doc,init< optional< const ellipse_2_trait& > >())
        .def(init< const Point_2&, optional< const ellipse_2_trait& > >(Min_ellipse_init_doc))
        .def(init< Point_2, Point_2, optional< const ellipse_2_trait& > >())
        .def(init< const Point_2&, const Point_2&, const Point_2&, optional< const ellipse_2_trait& > >())
        .def(init< const Point_2&, const Point_2&, const Point_2&, const Point_2&, optional< const ellipse_2_trait& > >())
        .def(init< const Point_2&, const Point_2&, const Point_2&, const Point_2&, const Point_2&, optional< const ellipse_2_trait& > >())
	.def("insert",(void  (Min_ellipse_2::*)(const Point_2&))&Min_ellipse_2::insert,Min_ellipse_insert_doc)
	.def("insert",&insert_list<Min_ellipse_2>)
        .def("number_of_points", &Min_ellipse_2::number_of_points,Min_ellipse_number_of_points_doc)
        .def("number_of_support_points", &Min_ellipse_2::number_of_support_points,Min_ellipse_number_of_support_points_doc)
        .def("is_empty", &Min_ellipse_2::is_empty,Min_ellipse_is_empty_doc)
        .def("is_degenerate", &Min_ellipse_2::is_degenerate,Min_ellipse_is_degenerate_doc)
        .def("support_point", &Min_ellipse_2::support_point, return_value_policy< copy_const_reference >(),Min_ellipse_support_point_doc)
        .def("ellipse", &Min_ellipse_2::ellipse, return_value_policy< copy_const_reference >(),Min_ellipse_ellipse_doc)
        .def("bounded_side", &Min_ellipse_2::bounded_side,Min_ellipse_bounded_side_doc)
        .def("has_on_bounded_side", &Min_ellipse_2::has_on_bounded_side,Min_ellipse_has_on_bounded_side_doc)
        .def("has_on_boundary", &Min_ellipse_2::has_on_boundary,Min_ellipse_has_on_boundary_doc)
        .def("has_on_unbounded_side", &Min_ellipse_2::has_on_unbounded_side,Min_ellipse_has_on_unbounded_side_doc)
        .def("clear", &Min_ellipse_2::clear,Min_ellipse_clear_doc)
        .def("is_valid", &Min_ellipse_2::is_valid, is_valid_overloads_0_2(Min_ellipse_is_valid_doc))
	.add_property("points",&points<Point_iterator,Min_ellipse_2>)
	.add_property("support_points",&support_points<Support_point_iterator,Min_ellipse_2>)
    ;
}

void export_Min_ellipse_2()
{
	Py_Min_ellipse_2<K>();
}
